import json
import random
import socket
import requests


def get_ip() -> dict:
    """
    当无法访问api获取公网ip时返回None
    :return: (ipv4,public_ip) 或者 None
    """
    hostname = socket.gethostname()
    data = {}
    ipv4_address = socket.gethostbyname(hostname)
    data['ipv4'] = ipv4_address
    try:
        response = requests.get('https://api64.ipify.org?format=json')
        if response.status_code == 200:
            data['public'] = response.json()['ip']
    except requests.exceptions.RequestException:
        return None
    return data


def get_port(n):
    """
    查找已经打开的端口，并返回在(10000,65535)范围内的端口
    n为一个大于等于1的int
    :return:
    """
    opened_port_list = []
    test_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    test_socket.settimeout(1)
    loop = 0
    for port in range(10000, 65536):
        if loop > n:
            break
        try:
            test_socket.connect(('127.0.0.1', port))
            opened_port_list.append(port)
            test_socket.close()
            loop += 1
        except socket.error:
            continue
    return opened_port_list


class port_dict:
    def __init__(self, n, d_port, open_port):
        self._number_port = n
        self._port_dict = {}
        self.d_port = d_port
        self.open_port = open_port

    def init_port_dict(self):
        if self.d_port:
            port_list = get_port(self._number_port)
            for port in port_list:
                self._port_dict[port] = False

    def get_port_dict(self):
        return self._port_dict

    def get_port(self):
        """
        返回一个在端口字典中的可用端口,当端口字典中的所有端口不可用时返回0
        """
        if self.d_port:
            for _port in self._port_dict:
                if not self._port_dict[_port]:
                    return _port
            return 0
        else:
            return self.open_port

    def change(self, port, status):
        """
        改变端口的信息
        """
        if self.d_port:
            if self._port_dict[port] == status:
                return
            self._port_dict[port] = status

    def delete_port_dict_data(self):
        self._port_dict.clear()


if __name__ == '__main__':
    ips = get_ip()

    if ips is None:
        print("无法正常获取公网ip地址")
    else:
        print(f"内网ip:{ips['ipv4']},公网ip:{ips['public']}")
